﻿using System;
using System.IO;

namespace geekcmd
{
	class FileInfo
	{
		#region Constructors
		FileInfo(DateTime modifiedTime, ulong size, string name, uint attributes)
		{
			this.ModifiedTime = modifiedTime;
			this.Size = size;
			this.Name = name;
			this.Extension = System.IO.Path.GetExtension(name);
			this.Attributes = (FileAttributes)attributes;
		}

		internal FileInfo(Win32Native.WIN32_FIND_DATA data)
			: this(DateTime.FromFileTimeUtc((long)data.ftCreationTimeHigh << 32 | data.ftCreationTimeLow),
				(ulong)data.nFileSizeHigh << 32 | data.nFileSizeLow, data.cFileName, data.dwFileAttributes)
		{
		}

		internal FileInfo(string name, Win32Native.WIN32_FILE_ATTRIBUTE_DATA data)
			: this(DateTime.FromFileTimeUtc((long)data.ftCreationTimeHigh << 32 | data.ftCreationTimeLow),
				(ulong)data.nFileSizeHigh << 32 | data.nFileSizeLow, name, data.dwFileAttributes)
		{
		}
		#endregion

		#region Properties
		public DateTime ModifiedTime { get; private set; }

		public ulong Size { get; private set; }

		public string Name { get; private set; }

		public string Extension { get; private set; }

		public FileAttributes Attributes { get; private set; }

		public bool Directory
		{
			get { return (Attributes & FileAttributes.Directory) != 0; }
		}
		#endregion

		#region Comparsion
		public static int CompareByTime(FileInfo lhs, FileInfo rhs)
		{
			if (lhs.Directory ^ rhs.Directory)
			{
				if (lhs.Directory)
				{
					return -1;
				}
				return 1;
			}
			else
			{
				int res = lhs.ModifiedTime.CompareTo(rhs.ModifiedTime);
				if (res == 0)
				{
					return lhs.Name.CompareTo(rhs.Name);
				}
				return res;
			}
		}

		public static int CompareBySize(FileInfo lhs, FileInfo rhs)
		{
			if (lhs.Directory ^ rhs.Directory)
			{
				if (lhs.Directory)
				{
					return -1;
				}
				return 1;
			}
			else if (lhs.Directory && rhs.Directory)
			{
				return lhs.Name.CompareTo(rhs.Name);
			}
			else
			{
				int res = lhs.Size.CompareTo(rhs.Size);
				if (res == 0)
				{
					return lhs.Name.CompareTo(rhs.Name);
				}
				return res;
			}
		}

		public static int CompareByName(FileInfo lhs, FileInfo rhs)
		{
			if (lhs.Directory ^ rhs.Directory)
			{
				if (lhs.Directory)
				{
					return -1;
				}
				return 1;
			}
			else
			{
				return lhs.Name.CompareTo(rhs.Name);
			}
		}

		public static int CompareByExtension(FileInfo lhs, FileInfo rhs)
		{
			if (lhs.Directory ^ rhs.Directory)
			{
				if (lhs.Directory)
				{
					return -1;
				}
				return 1;
			}
			else if (lhs.Directory && rhs.Directory)
			{
				return lhs.Name.CompareTo(rhs.Name);
			}
			else
			{
				int res = lhs.Extension.CompareTo(rhs.Extension);
				if (res == 0)
				{
					return lhs.Name.CompareTo(rhs.Name);
				}
				return res;
			}
		}
		#endregion
	}
}
